﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Xml.Linq;
using YBBEST.Office365Portal.Core.SPListWS;

namespace YBBEST.Office365Portal.Core
{
    public class ListsRespository : IListsRepository
    {
        private readonly IProxyConfiguration configuration;
        private readonly IServiceConnection serviceConnection;
        private readonly string listsAsmxEndpoint;

        public ListsRespository(IProxyConfiguration configuration, IServiceConnection serviceConnection)
        {
            this.configuration = configuration;
            this.serviceConnection = serviceConnection;
            listsAsmxEndpoint = string.Format("{0}_vti_bin/Lists.asmx", configuration.SiteUrl);
        }

        public void CreateNewList(string listName, string listDescription, int templateID)
        {
            string username = configuration.Username;
            string password = configuration.Password;
            string siteUrl = configuration.SiteUrl;
            string listsAsmxEndpoint = string.Format("{0}_vti_bin/Lists.asmx", siteUrl);
            MsOnlineClaimsHelper claimsHelper = new MsOnlineClaimsHelper(username, password, siteUrl);
            HttpRequestMessageProperty p = new HttpRequestMessageProperty();
            var cookie = claimsHelper.CookieContainer;
            string cookieHeader = cookie.GetCookieHeader(new Uri(siteUrl));
            p.Headers.Add("Cookie", cookieHeader);
            using (ListsSoapClient proxy = new ListsSoapClient())
            {
                proxy.Endpoint.Address = new EndpointAddress(listsAsmxEndpoint);

                using (new OperationContextScope(proxy.InnerChannel))
                {
                    OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = p;
                    //http://blogs.msdn.com/b/yardman/archive/2010/08/31/sharepoint-list-template-ids.aspx
                    proxy.AddList(listName, listDescription, templateID);
                }

            }
        }
        public IList<SharePointList> RetrieveAllLists()
        {
            IList<SharePointList> sharepointLists = new List<SharePointList>();
            string username = configuration.Username;
            string password = configuration.Password;
            string siteUrl = configuration.SiteUrl;
            string listsAsmxEndpoint = string.Format("{0}_vti_bin/Lists.asmx", siteUrl);



            MsOnlineClaimsHelper claimsHelper = new MsOnlineClaimsHelper(username, password, siteUrl);
            HttpRequestMessageProperty p = new HttpRequestMessageProperty();
            var cookie = claimsHelper.CookieContainer;
            string cookieHeader = cookie.GetCookieHeader(new Uri(siteUrl));
            p.Headers.Add("Cookie", cookieHeader);
            using (ListsSoapClient proxy = new ListsSoapClient())
            {
                proxy.Endpoint.Address = new EndpointAddress(listsAsmxEndpoint);

                using (new OperationContextScope(proxy.InnerChannel))
                {
                    OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = p;
                    //http://blogs.msdn.com/b/yardman/archive/2010/08/31/sharepoint-list-template-ids.aspx
                    XElement spLists = proxy.GetListCollection();
                    foreach (var el in spLists.Descendants())
                    {
                        foreach (var attrib in el.Attributes())
                        {
                            if (attrib.Name.LocalName.ToLower() == "title")
                            {
                                var list = new SharePointList
                                               {
                                                   Title = attrib.Value
                                               };
                                sharepointLists.Add(list);
                            }
                        }
                    }
                }


            }
            return sharepointLists;
        }

        public SharePointList RetrieveListByName(string listName)
        {
            string username = configuration.Username;
            string password = configuration.Password;
            string siteUrl = configuration.SiteUrl;
            string listsAsmxEndpoint = string.Format("{0}_vti_bin/Lists.asmx", siteUrl);
            MsOnlineClaimsHelper claimsHelper = new MsOnlineClaimsHelper(username, password, siteUrl);
            HttpRequestMessageProperty p = new HttpRequestMessageProperty();
            var cookie = claimsHelper.CookieContainer;
            string cookieHeader = cookie.GetCookieHeader(new Uri(siteUrl));
            p.Headers.Add("Cookie", cookieHeader);
            using (ListsSoapClient proxy = new ListsSoapClient())
            {
                proxy.Endpoint.Address = new EndpointAddress(listsAsmxEndpoint);
                using (new OperationContextScope(proxy.InnerChannel))
                {
                    OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = p;
                    //http://blogs.msdn.com/b/yardman/archive/2010/08/31/sharepoint-list-template-ids.aspx
                    XElement listXmlElement = proxy.GetList(listName);

                    XDocument document = XDocument.Parse(listXmlElement.ToString());
                    string listTitle = document.Root.Attribute("Title").Value;
                    return new SharePointList { Title = listTitle };
                }

            }
        }

        public void DeleteListByName(string listName)
        {
            string username = configuration.Username;
            string password = configuration.Password;
            string siteUrl = configuration.SiteUrl;
            MsOnlineClaimsHelper claimsHelper = new MsOnlineClaimsHelper(username, password, siteUrl);
            HttpRequestMessageProperty p = new HttpRequestMessageProperty();
            var cookie = claimsHelper.CookieContainer;
            string cookieHeader = cookie.GetCookieHeader(new Uri(siteUrl));
            p.Headers.Add("Cookie", cookieHeader);
            using (ListsSoapClient proxy = new ListsSoapClient())
            {
                proxy.Endpoint.Address = new EndpointAddress(listsAsmxEndpoint);
                using (new OperationContextScope(proxy.InnerChannel))
                {
                    OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = p;
                    proxy.DeleteList(listName);
                }
            }
        }

        public List<string> DisplayListItems(string item)
        {
            serviceConnection.ConfigureAuthenticationRequestCookie();
            var res = new List<string>();
            using (var proxy = new ListsSoapClient())
            {
                serviceConnection.SetEndpoint(proxy, listsAsmxEndpoint);
                using (new OperationContextScope(proxy.InnerChannel))
                {
                    serviceConnection.SetOutgoingMessageProperties();

                    // QueryOptions can have "<IncludeMandatoryColumns>FALSE</IncludeMandatoryColumns>"
                    var ndListItems = proxy.GetListItems(item, null, new XElement("Query"), new XElement("ViewFields"), null, new XElement("QueryOptions"), null);
                    res = ndListItems == null ? res : ndListItems.Descendants().Where(d => d.Name.LocalName == "row").SelectMany(d => d.Attributes()).Where(a => a.Name == "ows_LinkFilename").Select(a => a.Value).ToList();
                }
            }
            return res;
        }

        public void CheckOutFile(string item)
        {
            var fileUrl = configuration.SiteUrl + item;
            serviceConnection.ConfigureAuthenticationRequestCookie();
            using (var proxy = new ListsSoapClient())
            {
                serviceConnection.SetEndpoint(proxy, listsAsmxEndpoint);
                using (new OperationContextScope(proxy.InnerChannel))
                {
                    serviceConnection.SetOutgoingMessageProperties();

                    proxy.CheckOutFile(fileUrl, "NoName", string.Empty);
                }
            }
        }
    }
}

